/**********************************************************************************
// SceneManager Header File
//
// Creation:	31 Ago 2007
// Updated:		27 Set 2009
// Compiler:	Visual Studio 2008
//
// Notes:		Defines a Scene Manager to deal with game objects
//
**********************************************************************************/

#ifndef _ANABELE_SCENEMANAGER_H_
#define _ANABELE_SCENEMANAGER_H_

#pragma warning (disable: 4251) // list needs dll-interface warnings

/**********************************************************************************/

#include <list>
#include <algorithm>
#include <iterator>
#include <utility>
#include "Geometry.h"
#include "Sprite.h"
using std::list;
using std::pair;

/**********************************************************************************/

class DLL SceneManager
{
private:
	list<GameObject*> staticGameObjs;					// vector of pointers to game objects
	list<GameObject*> movingGameObjs;					// vector of pointers to game objects
	list<pair<GameObject*,GameObject*>> collisions;		// vector of pairs of pointers to game objects
	list<GameObject*>::iterator objI;					// iterator for game objects
	list<GameObject*>::iterator objJ;					// iterator for game objects

protected:
	bool Collision(GameObject& oa, GameObject& ob);		// collision between objects
	
	bool Collision(Point& pa, Point& pb);				// collision between points	
	bool Collision(Circle& ca, Circle& cb);				// collision between circles
	bool Collision(Rect& ra, Rect& rb);					// collision between rectangles
	bool Collision(Poly& pa, Poly& pb);					// collision between polygons
	bool Collision(Sprite& pa, Sprite& pb);				// collision between sprites
	
	bool Collision(Point& p, Circle& c);				// collision between point and circle
	bool Collision(Circle& c, Point& p)					// collision between point and circle
	{ return Collision(p,c); }

	bool Collision(Point& p, Rect& r);					// collision between point and rectangle
	bool Collision(Rect& r, Point& p)					// collision between point and rectangle
	{ return Collision(p,r); }

	bool Collision(Point& p, Poly& pol);				// collision between point and polygon
	bool Collision(Poly& pol, Point& p)					// collision between point and polygon
	{ return Collision(p, pol); }

	bool Collision(Circle& c, Rect& r);					// collision between circle and rectangle
	bool Collision(Rect& r, Circle& c)					// collision between circle and rectangle
	{ return Collision(c,r); } 					
	
	bool Collision(Circle& c, Poly& pol);				// collision between circle and polygon
	bool Collision(Poly& pol, Circle& c)				// collision between circle and polygon
	{ return Collision(c, pol); }

	bool Collision(Rect& r, Poly& pol);					// collision between rectangle and polygon
	bool Collision(Poly& pol, Rect& r)					// collision between rectangle and polygon
	{ return Collision(r, pol); }

	
	bool Collision(Sprite& s, GameObject& g);			// collision between sprite and object
	bool Collision(GameObject& g, Sprite& s)			// collision between sprite and object
	{ return Collision(s, g); }

public:
	void RegisterMoving(GameObject &obj);				// register a moving object
	void RegisterStatic(GameObject &obj);				// register a static object
	void UnRegisterStatic(GameObject &obj);				// unregister a static object
	void UnRegisterMoving(GameObject &obj);				// unregister a moving object
	bool CollisionDetection();							// populate list of objects that are in colision
	pair<GameObject*,GameObject*> OnCollisionObjects();	// get objects in collision
};

/**********************************************************************************/

inline bool SceneManager::Collision(Sprite& pa, Sprite& pb)
{ return Collision(*((GameObject*) pa.boundingbox), *((GameObject*) pb.boundingbox)); }

inline bool SceneManager::Collision(Sprite& s, GameObject& g)
{ return Collision(*((GameObject*) s.boundingbox), g); }

/**********************************************************************************/	

#endif

